/*
 * PreLogin
 * 
 * Version information
 * 
 * Feb 25, 2006
 * 
 * Copyright (c) AmSoft Systems, 2006
 */
package net.amsoft.iservice.isso.webapp.struts.action;

import java.util.HashMap;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.amsoft.iservice.isso.client.ISSOClient;
import net.amsoft.iservice.isso.webapp.dataObject.LoginData;
import net.amsoft.iservice.isso.webapp.dataObject.SPData;
import net.amsoft.iservice.util.IServiceUtil;
import net.amsoft.iservice.util.MetaData;
import net.amsoft.iservice.isso.webapp.struts.form.LoginForm;
import net.amsoft.iservice.isso.service.ISSOService;
import net.amsoft.iservice.isso.util.ISSOConstants;
import net.amsoft.iservice.util.ResolverClient;
import net.amsoft.iservice.util.exception.IServiceException;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

/**
 * @author rahul
 * 
 */
public class PreLogin extends BaseAction {
	private static final Logger oLogger = Logger.getLogger(PreLogin.class);
    public ActionForward process(ActionMapping oMapping, ActionForm oForm,
            HttpServletRequest oRequest, HttpServletResponse oResponse)
            throws Exception {
    	oLogger.info("process() : entry");
        ActionMessages oMessages = new ActionErrors();
        try {
            LoginData oLoginData = (LoginData) oRequest.getSession(false)
                    .getAttribute(ISSOConstants.SESSION_LOGIN_OBJ);
            LoginForm oLoginForm = (LoginForm) oForm;
            // Resolution
            oLogger.info("process() : I-Name="+ oLoginForm.getIname());
            MetaData oMetadata = ResolverClient.getFinalMetaData(oLoginForm
                    .getIname());
            
            if (oMetadata == null) {
                ResourceBundle oBundle = ResourceBundle
                        .getBundle("issoResources", oRequest.getLocale());
                throw new IServiceException(oBundle
                        .getString(ISSOConstants.ERR_INAME_NOT_FOUND), 2034);
            }
            String sGlobalInumber = oMetadata.getGlobalInumber();
            String sIBroker = oRequest.getServerName();
            oLogger.info("process() : GlobalInumber="+ sGlobalInumber+", IBroker=" + sIBroker);
            
            // Verify if the iname belongs to the same IBroker
            if (!ISSOService.verifySynonym(sGlobalInumber, oLoginForm
                    .getIname(), sIBroker)) {
            	oLogger.error("process() : Message : Synonym not verified, ExceptionCode=2010");
            	throw new IServiceException(oLogger, 2010);
            }
            String sISSOUrl = oMetadata.getISSOUrl();
            String providerID = oMetadata.getProviderID();
            
            oLogger.debug("process() : ProviderId=" + providerID+", SSOURl=" + sISSOUrl);
                        
            oLogger.debug("process() : RAC Names List -> "+ ISSOConstants.RAC_NAMES_LIST);
            oLogger.debug("process() : RAC Comparison Type -> "+ ISSOConstants.RAC_COMPARISON_TYPE);
            String[] authnContext = ISSOConstants.RAC_NAMES_LIST.split(",");
            String sComparison = ISSOConstants.RAC_COMPARISON_TYPE;
            String sAuthRequest = ISSOClient.createSAMLAuthRequest(
                    sGlobalInumber, "", ISSOConstants.getSPXri(oRequest
                            .getServerName()), false, oRequest.getServerName(),
                    false, authnContext, sComparison);
            oLogger.info("process() : AuthnContext="+ authnContext + " Comparison=" + sComparison);
            
            HashMap ohSPData = (HashMap) oRequest.getSession(false)
                    .getAttribute(ISSOConstants.SESSION_LOGIN_HASH_OBJ);

            String sSpXri = ISSOConstants.getSPXri(oRequest.getServerName());
            SPData oSPData = (SPData) ohSPData.get(sSpXri);

            if (oSPData == null)
                oSPData = new SPData();

            String sRelayState = IServiceUtil.generateUniqueID();
            oLoginData.setLoggedInSynonym(oLoginForm.getIname());
            oSPData.setGlobalInumber(sGlobalInumber);
            oSPData.setRelayState(sRelayState);
            oSPData.setProviderID(providerID);
            oSPData.setProviderIDHash(IServiceUtil
                    .getOneWayEncValue(providerID));
            oLoginData.setIDPMetaDataEP(oMetadata.getServiceEndPoint());
            ohSPData.put(sSpXri, oSPData);

            oLogger.info("process() : Exit, Forward="+ sISSOUrl);
            return new ActionForward(ISSOClient.getRedirectRequestURI(sISSOUrl,
                    sAuthRequest, sRelayState), true);

        } catch (IServiceException e) {
        	oLogger.warn("process() : Exception : "+e.getMessage());
        	if (e.getErrorCode() == 2007) {
				oMessages.add(ActionMessages.GLOBAL_MESSAGE,
						new ActionMessage(
								ISSOConstants.MSG_ACCOUNT_NOT_ACTIVE));
			} 
        	else {
				oMessages.add(ActionMessages.GLOBAL_MESSAGE,
						new ActionMessage(((IServiceException) e)
								.getMessage(), false));
			}        	
            saveErrors(oRequest, oMessages);
            oLogger.error("process() : Exit, Exception="+ e.getErrorCode()+ ", Forward to Iname");
            return oMapping.findForward(ISSOConstants.INAME_FWD);
        }
    }
}